#! /usr/bin/env python
#coding=utf-8

import os
import sys

from .symbols import ElfSymbolRest

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
from utils import ResterHelper

import graphviz

class ModuleQuerier(object):
	def __init__(self, keys):
		self._keys = keys

	def get_keys(self, xargs=None):
		return tuple(self._keys)

	def match(self, key):
		if key in self._keys:
			return True
		return False

	def query(self, elf, key, cursor, xargs):
		return None

class ElfModuleSymbolQuerier(ModuleQuerier):
	QUERY_KEYS = ( "provided", "public_symbols", "used", "unused", "needed", "matched", "unmatched", "duplicated" )
	QUERY_METHODS = ( ("getProvidedSymbols", ElfSymbolRest),
					  ("getPublicSymbols", ElfSymbolRest),
					  ("getProvidedSymbolsUsed", ElfSymbolRest),
					  ("getProvidedSymbolsUnused", ElfSymbolRest),
					  ("getUndefinedSymbols", ElfSymbolRest),
					  ("getUndefinedSymbolsMatched", ElfSymbolRest),
					  ("getUndefinedSymbolsDuplicated", ElfSymbolRest),
					  ("getUndefinedSymbolsUnmatched", ElfSymbolRest) )

	def __init__(self):
		super(ElfModuleSymbolQuerier, self).__init__(ElfModuleSymbolQuerier.QUERY_KEYS)

	def query(self, elf, key, cursor, xargs):
		idx = self._keys.index(key)
		name, cls = ElfModuleSymbolQuerier.QUERY_METHODS[idx]
		symbols = elf.callByFunctionName(name, cursor, cls)

		return ResterHelper.build_array_content(symbols, xargs)

class ElfModuleSizeInfoQuerier(ModuleQuerier):
	QUERY_KEYS = ("size", "text_size", "data_size", "oc_size", "others_size", "processes", "Pss", "swapPss", "Shared_Dirty", "Private_Dirty" )

	def __init__(self):
		super(ElfModuleSizeInfoQuerier, self).__init__(ElfModuleSizeInfoQuerier.QUERY_KEYS)

class ElfModuleDepsQuerier(ModuleQuerier):
	QUERY_KEYS = ("deps", "dependedBy")

	def __init__(self):
		super(ElfModuleDepsQuerier, self).__init__(ElfModuleDepsQuerier.QUERY_KEYS)

	def get_keys(self, xargs=None):
		return ElfModuleDepsQuerier.QUERY_KEYS

	def query(self, elf, key, cursor, xargs):
		vals = elf[key]
		if graphviz.requestingGraphviz(xargs):
			return elf.plotGraph(xargs)
		return ResterHelper.build_array_content(vals, xargs)

class ElfModuleInfoQuerierMgr(object):
	QUERIERS = ( ElfModuleDepsQuerier(), ElfModuleSymbolQuerier(), ElfModuleSizeInfoQuerier() )

	@staticmethod
	def get_all_keys(xargs=None):
		res = ()
		queriers = ElfModuleInfoQuerierMgr.QUERIERS
		for q in queriers:
			res = res + q.get_keys(xargs)
		if xargs and "format" in xargs and xargs["format"] in ("xml", "json"):
			res = res + ("path", "category")
		return res

	@staticmethod
	def query(elf, key, cursor, xargs):
		for q in ElfModuleInfoQuerierMgr.QUERIERS:
			if not q.match(key):
				continue
			return q.query(elf, key, cursor, xargs)

		return ""
